package com.lucenex.service;



import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;

import com.lucenex.base.BaseLuceneXDao;
import com.lucenex.core.LuceneDataSource;
import com.lucenex.util.ObjectKit;
import com.lucenex.util.Page;

public class LuceneServiceImpl implements LuceneService {
	
	private BaseLuceneXDao indexDao;
	
	//必须这样实现
	public LuceneServiceImpl(String sourceKey) throws IOException{
		LuceneDataSource.setDatabaseType(sourceKey);
		indexDao = new BaseLuceneXDao();
	}


	@Override
	public <T> void saveObj(List<T> object) throws IOException, IllegalAccessException {
		List<Document> documents = new ArrayList<>();
		int size = object.size();
		for(int i=0;i<size;i++) {
			documents.add(ObjectKit.builder().obj(object.get(i)).build().document());
		}
		saveDocument(documents);
	}


	@Override
	public <T> void saveObj(T object) throws IOException, IllegalAccessException {
		saveDocument(ObjectKit.builder().obj(object).build().document());
	}
	
	@Override
	public <T> void saveMap(List<T> map, Class<?> clas)
			throws IOException, IllegalAccessException {
		List<Document> documents = new ArrayList<>();
		int size = map.size();
		for (int i = 0; i < size; i++) {
			documents.add(ObjectKit.builder().obj(map.get(i)).type(clas).build().document());
		}
		saveDocument(documents);
	}


	@Override
	public <T> void saveMap(T map, Class<?> clas) throws IOException, IllegalAccessException {
		saveDocument(ObjectKit.builder().obj(map).type(clas).build().document());
	}


	@Override
	public <T> void saveDocument(List<Document> documents) throws IOException {
		indexDao.saveIndex(documents);
	}


	@Override
	public <T> void saveDocument(Document document) throws IOException {
		indexDao.saveIndex(document);
	}


	@Override
	public <T> void updateObj(List<T> objs, Term term) throws IOException, IllegalAccessException {
		List<Document> documents = new ArrayList<>();
		int size = objs.size();
		for(int i=0;i<size;i++) {
			documents.add(ObjectKit.builder().obj(objs.get(i)).build().document());
		}
		updateDocument(documents, term);
	}


	@Override
	public <T> void updateObj(T obj, Term term) throws IOException, IllegalAccessException {
		updateDocument(ObjectKit.builder().obj(obj).build().document(), term);
	}
	
	@Override
	public <T> void updateObj(List<T> object, Query query)throws Exception {
		List<Document> documents = new ArrayList<>();
		int size = object.size();
		for(int i=0;i<size;i++) {
			documents.add(ObjectKit.builder().obj(object.get(i)).build().document());
		}
		updateDocument(documents, query);
		
	}


	@Override
	public <T> void updateObj(T object, Query query)throws Exception{
		updateDocument(ObjectKit.builder().obj(object).build().document(), query);
	}

	
	@Override
	public <T> void updateMap(List<T> map, Term term, Class<?> clas)
			throws IOException, IllegalAccessException {
		List<Document> documents = new ArrayList<>();
		int size = map.size();
		for(int i=0;i<size;i++) {
			documents.add(ObjectKit.builder().obj(map.get(i)).type(clas).build().document());
		}
		updateDocument(documents, term);
	}


	@Override
	public <T> void updateMap(T map, Term term, Class<?> clas)
			throws IOException, IllegalAccessException {
		updateDocument(ObjectKit.builder().obj(map).type(clas).build().document(), term);
	}
	
	@Override
	public <T> void updateMap(List<T> map, Query query, Class<?> clas)throws Exception{
		List<Document> documents = new ArrayList<>();
		int size = map.size();
		for(int i=0;i<size;i++) {
			documents.add(ObjectKit.builder().obj(map.get(i)).type(clas).build().document());
		}
		updateDocument(documents, query);
		
	}


	@Override
	public <T> void updateMap(T map, Query query, Class<?> clas)throws Exception{
		updateDocument(ObjectKit.builder().obj(map).type(clas).build().document(), query);
	}



	@Override
	public void updateDocument(List<Document> docs, Term term) throws IOException {
		indexDao.updateIndex(docs, term);
	}


	@Override
	public void updateDocument(Document doc, Term term) throws IOException {
		indexDao.updateIndex(doc, term);
		
	}
	@Override
	public void updateDocument(List<Document> document, Query query) throws Exception {
		indexDao.updateIndex(document, query);
	}


	@Override
	public void updateDocument(Document document, Query query) throws Exception {
		indexDao.updateIndex(document, query);
	}


	@Override
	public <T> List<T> findList(Query query, Class<T> obj, int num, Sort sort) throws IOException, InvalidTokenOffsetsException, InstantiationException, IllegalAccessException, NoSuchFieldException, InvocationTargetException {
		return indexDao.findList(query, obj, num, sort);
	}


	@Override
	public <T> Page<T> findList(Query query, int pageNumber, int pageSize, Class<T> obj, Sort sort) throws IOException, InvalidTokenOffsetsException, InstantiationException, IllegalAccessException, NoSuchFieldException, InvocationTargetException {
		return indexDao.findList(query, pageNumber, pageSize, obj, sort);
	}
	
	
	@Override
	public void delAll() throws IOException {
		indexDao.delAll();
	}


	@Override
	public void delKey(Term term) throws IOException {
		indexDao.deletekey(term);
	}


	@Override
	public void delKey(Query query) throws IOException {
		indexDao.deletekey(query);
	}
}
